/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/
#include "kinifile.h"
#include "kengine.h"
#include "kresources.h"
#include "kmemorystream.h"
#include "ktextreader.h"
#include "ktextwriter.h"

kIniFile::kIniFile(kEngine* engine) {
	_engine = engine;
}
kIniFile::~kIniFile() {
}
void kIniFile::save(kStream* stream) {
	kTextWriter writer(stream);

	for (auto i = _data.begin(); i != _data.end(); i++) {
		if (i->first.length()) {
			writer.writeLn();
			writer.writeLn(_T("[") + i->first + _T("]"));
			for (auto j = i->second.begin(); j != i->second.end(); j++) {
				writer.writeLn(j->first + _T("=") + j->second);
			}
		}
	}
}
void kIniFile::load(kStream* stream) {
	kTextReader reader(stream);

	std::tstring groupName = _T("");
	std::tstring line;

	const tchar* whitespace = kDefaultEncoding<>::whitespace;

	while (reader.readLn(line)) {
		size_t i = line.find_first_not_of(whitespace);

		if (i != std::tstring::npos) {
			switch (line[i]) {
			case _T(';'):
				break;
			case _T('['):
				{
					size_t j = line.find(_T(']'), i+1);
					if (j == std::tstring::npos || (line.find_last_not_of(whitespace) != j))
						throw kError(_T("Invalid ini file"));
					groupName = line.substr(i+1, j-i-1);
				}
				break;
			default:
				{
					size_t j = line.find(_T('='), i);
					if (j == std::tstring::npos)
						throw kError(_T("Invalid ini file"));
					size_t k = j ? line.find_last_not_of(whitespace, j-1) : 0;
					std::tstring key = line.substr(i, k+1-i);
					k = line.find_first_not_of(whitespace, j+1);
					std::tstring value = line.substr(k, line.find_last_not_of(whitespace) + 1 - k);
					_data[groupName][key] = value;
				}
				break;
			}
		}
	}
}
void kIniFile::save(const std::tstring& resourceUri) {
	kMemoryStream stream;
	save(&stream);
	_engine->getResources()->update(resourceUri, &stream);
}
void kIniFile::load(const std::tstring& resourceUri) {
	kResources* resources = _engine->getResources();
	kStream* stream = resources->open(resourceUri);
	load(stream);
	resources->close(stream);
}
